import * as React from "react";
// import {isHoverEnabled} from "customize-easy-ui-component/esm/Hooks/hover-enabled";
import { isHoverEnabled } from "./hover-enabled";



export type OnPressFunction = (
    e?: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event
) => void;

export interface PressableOptions {
    behavior?: "button" | "link";
    disabled?: boolean;
    onPress?: OnPressFunction;
    //noHover=true： 不要了：因为鼠标经过京会导致毛病，滚动条闪了，窗口焦点跑远了，render多了
    noHover?: boolean;
}
//HOOK返回类型:
export interface PressableResult {
    //手机上没有
    hover: boolean;
    bind: {
        onKeyDown: (e: React.KeyboardEvent) => void;
        onKeyUp: (e: React.KeyboardEvent) => void;
        // ref: React.MutableRefObject<any>;
        onMouseEnter: (e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event) => void;
        onMouseLeave: (e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event) => void;
        //直接上
        onClick?: ((e: React.MouseEvent<Element, MouseEvent>) => void) | undefined;
        onPointerDown: (e: (React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event)) => void;
        // onPointerUp: (e: (React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event)) => void;
        // onPointerCancel: (e: (React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event)) => void;
        onPointerOut: (e: (React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event)) => void;
    };
    //改版后已无效
    active: boolean
}

/**表示某一个小div区域可以按下点击 触发函数。 返回bind? 同一个名字onXXX()可能冲突;
 * 点按 不是拖拽拉动的，相对位置是静止的，按住时间长短？才算，立刻反馈被您点到了。
 * Hook：原版乃是touchable-hook这个包的。
 触摸屏和配置鼠标设备的浏览器下：可能有差异。
 */
export function usePressable(
    {
         onPress,
         behavior="button",
         disabled=false,
         noHover=false,
     }: PressableOptions ) : PressableResult
{
    // const ref = React.useRef<HTMLAnchorElement | HTMLDivElement | any>(null);
    //hover是鼠标覆盖到了DIV区域，响应高亮用。
    const [hover, setHover] = React.useState(false);
    //active表示被按到：但是接着也可能取消的。
    const [active, setActive] = React.useState(false);

    /** 加个条件 active==true 才能真的 emitPress;?
     * 直接依赖于状态机切换的： active和emitPress是平行身份，onPress不直接取决于active。
     * Emit a press event if not disabled
     * @param e
     */
    function emitPress(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event
    ) {
        if (!disabled && onPress) {
            //缺少历史状态管理： 拉拽时刻： 意味着取消当前的Item的 onClick??  PointerEvent offsetX
            onPress(e);
        }
        active && setActive(false);
    }

    /** 鼠标模式:
     * If our mouse leaves we terminate our responder,
     * even if our press remains down. This emulates
     * native mouse behaviour.
     * @param e
     */
    function onMouseLeave(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event) {
        if(!noHover){
            if (hover) {
                setHover(false);
            }
        }
    }

    function onMouseEnter(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event) {
        if(!noHover){
            if (!hover) {
                setHover(true);
            }
        }
    }

    //外部参数disabled导致的
    React.useEffect(() => {

    }, [disabled]);

    /** 键盘模式 直接就能触发！
     * 空格键  回车键。  Keyboard support ,必须是foucsed?
     *   onEnterDown -> onPress
     *   onSpaceUp -> onPress
     * Prevent default.
     * link: Don't prevent default
     */
    function onKey(e: React.KeyboardEvent) {
        if (e.type === "keyup" && e.key === " ") {
            emitPress(e);
        }
        else if (e.type === "keyup" && e.key === "Enter") {
            emitPress(e);
        }
        else {
            return;
        }
        //停止冒泡，就不会传递给上级组件Div了
        e.stopPropagation();

        if (!(e.key === "Enter" && behavior === "link")) {
            //阻止缺省行为
            e.preventDefault();
        }
    }

    function onPointerDown(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event ) {
        if(!disabled) {
            !active && setActive(true);
        }
    }
    // function onPointerUp(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event ) {
    // }
    // function onPointerCancel(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event ) {
    // }
    function onPointerOut(e: React.TouchEvent | React.MouseEvent | React.KeyboardEvent | Event ) {
        active && setActive(false);
    }


    /* 上级的轮播台无法触发 PointerUp事件了？
      "framer-motion"需要在主体窗口加上 pointer-events: none; 手机才能顺利拉得动listItem区域，这时该区域按钮也无效了。
      React中的合成事件:  https://cloud.tencent.com/developer/article/1779731?from=15425
    * */

    return {
        bind: {
            onMouseEnter,
            onMouseLeave,
            onKeyUp: onKey,
            onKeyDown: onKey,
            onPointerDown: onPointerDown,
            // ref,
            onClick: emitPress,
            // onPointerUp: onPointerUp,
            // onPointerCancel: onPointerCancel,
            onPointerOut: onPointerOut,
        },
        active: !disabled && active,
        hover: !disabled && (!noHover) && isHoverEnabled() && hover
    };
}


/*
Pointer Events* 提供了处理所有输入事件的统一方法。   https://zh-hans.reactjs.org/docs/events.html#pointer-events
合成事件SyntheticEvent；nativeEvent 属性；冒泡阶段被触发。
onpointerover	当指针设备移动到元素的命中测试边界时会触发 pointerover 事件
onpointercancel	当浏览器确定不可能再有任何指针事件时，将触发 pointercancel 事件，或者如果在触发 pointerdown 事件后，然后使用指针通过平移、缩放或滚动来操纵视口;
onpointerout	触发pointerout 事件有几个原因，包括：指针设备移出元素的命中测试边界； 为不支持悬停的设备触发 pointerup 事件（请参阅 pointerup）； 触发 pointercancel 事件后（参见 pointercancel）； 当触控笔离开数字化仪可检测的悬停范围时
onClickCapture
* */
